#include "constants.h";

XfMissionChapterExecute={
	private ["_chapter_succeeded"];
	diag_log "";
	diag_log "=========================================================================";
	diag_log "                             CHAPTER 1                                   ";
	diag_log "=========================================================================";
	diag_log "";
	diag_log Format["(%1)[%2]: %3; %4",diag_tickTime,"chapter1.sqf","XfMissionChapterExecute","Starting Chapter","_last_random_reinforcement","_random_reinf_diff","_reinforcement_power"];
	DM_Mission_ArtilleryVariables = [];
	DM_Mission_Chapter_CanRun = True;
	DM_Mission_Chapter_Runs = True;
	DM_Mission_Chapter_Success = 0;
	call XfMissionChapterSetup;
	_chapter_succeeded = false;
	if (!DM_Mission_Mission_CanRun) exitWith {diag_log Format["(%1)[%2]: %3; %4",diag_tickTime,"chapter1.sqf","XfMissionChapterSetup","Mission canceled!"];};

	_random_town = DM_Chapter_Location;
	_random_town_pos = _random_town select XF_MAP_LOCATION_CENTER;
	_random_town_pos_size = _random_town select XF_MAP_LOCATION_SIZE;
	_civ_grp = DM_VIP;
	
	_players = call XPlayersNumber;
	_enemy_troops = 2 + _players + DM_Mission_EnemyPower + DM_Mission_EnemyCoeff;
	_reinf_timer = 600;
	switch (true) do {
		case (_players <= 5): { _reinf_timer = 600 };
		case (_players <= 10): { _reinf_timer = 400 };
		case (_players <= 15): { _reinf_timer = 300 };
		case (_players <= 20): { _reinf_timer = 240 };
		default {_reinf_timer = 140;};
	};	
	_reinforcement = DM_Mission_RandomReinforcement + _players + DM_Mission_EnemyPower + DM_Mission_EnemyCoeff;
	_reinf_next = 0;
	_dir = 0;
	_active_enemies = 0;
	_civilians = [];
	_enemies = [];
	
	_players_found = false;
	while {DM_Mission_Chapter_CanRun AND DM_Mission_Mission_CanRun AND !_players_found} do {
		if (X_MP) then {
			_players_found = false;
			{
				if (([(getPos _x), _random_town_pos, _random_town_pos_size * 3] call XfPointInCircle) && isplayer _x && alive _x) exitWith { _players_found = true; };
			}foreach playableUnits;
		} else {
			if (alive player) then { _players_found = ([(getPos player), _random_town_pos, _random_town_pos_size * 3] call XfPointInCircle); };
		};
		sleep 15;
	};
	_attacking_groups = [];
	_initial_civ_count = 0;
	
	if (DM_Mission_Chapter_CanRun AND DM_Mission_Mission_CanRun) then {
		"STR_MF_M_POGROM_START" call XfMissionMessageToAll;
		sleep 20;
		
		_grp = [d_own_side] call x_creategroup;
		_grp setBehaviour "SAFE";
		_grp setSpeedMode "LIMITED";
		_grp setCombatMode "BLUE";
		_grp allowFleeing 1;
		deleteWaypoint [_grp, 0];
		(units _civ_grp) joinSilent _grp;	
		_civ_grp = _grp;
		_wp = _civ_grp addWaypoint [_random_town_pos, 10];
		_wp setWaypointSpeed "LIMITED";
		_wp setWaypointCompletionRadius (_random_town_pos_size * 2);
		_civ_grp setCurrentWaypoint _wp;		
		_civ_grp allowFleeing 1;
		[0, _civ_grp, "Civilians", "MissionFramework"] call ACV_FNCT_PutInStock;
		_civilians = units _civ_grp;
		
		// Hide civilians
		_building_hide_pos = [_random_town_pos,(_random_town_pos_size * 0.7), "INTERN", true] call XfMissionBuildingAreaPos;
		_civ_grp setSpeedMode "FULL";
		_wps = waypoints _civ_grp;
		for [{_i = 0}, {_i < (count (waypoints _civ_grp))}, { _i = _i + 1 }] do {
			deleteWaypoint [_civ_grp, _i];
		};
		{
			_pos = [];
			if (count _building_hide_pos > 0) then {
				_pos =(_building_hide_pos call XfRandomArrayVal);
			} else {
				_pos =([_random_town_pos, (_random_town_pos_size * 0.5)] call XfGetRanPointCircle);
			};
			if (d_mission_debug_messages) then {
				_mrk_name = Format["wp%1%2%3",(_pos) select 0,(_pos) select 1,round(random(100))];
				createMarkerLocal [_mrk_name, (_pos)];
				_mrk_name setMarkerAlphaLocal 0.5;
				_mrk_name setMarkerShapeLocal "ICON";
				_mrk_name setMarkerColorLocal "ColorRed";
				_mrk_name setMarkerTypeLocal "mil_triangle";
				_mrk_name setMarkerSizeLocal [0.5, 0.5];
			};
			_x setVariable ["MF_AI_STATUS","HIDING"];
			_x allowFleeing 1;
			_x setSkill 0.1;
			_x setSpeedMode "FULL";
			_killed_evt = {
				if (isserver) then {
					_msg = (_this select 0) getVariable "KilledMessageDone";
					if (isnil "_msg" && (_this select 2) >= 1 && (_this select 1) == "") then {
						(_this select 0) setVariable ["KilledMessageDone",true];
						"STR_MF_M_POGROM_KILLED" call XfMissionMessageToAll;
						
					};
				};
				_this select 2;
			};
			_eid = _x addEventHandler ["HandleDamage",_killed_evt];
			diag_log Format["(%1)[%2]: %3: %4: %5, %6",diag_tickTime,"chapter1.sqf","XfMissionChapterExecute","Civilian set",[_x,typeof _x,_eid], Time];
			[_x, _pos] spawn {
				private ["_civ","_hidepos","_start","_initpos"];
				_civ = _this select 0;
				doStop _civ;
				_hidepos = _this select 1;
				_start = time;
				_initpos = false;
				while {alive _civ} do {
					_civ doMove _hidepos;
					if (_civ distance _hidepos > 2 && !_initpos) then {
						if ((time - _start) > 90) then {
							_civ setPos _hidepos;
							_initpos = true;
						};
					};
					sleep 10;
				};
				diag_log Format["(%1)[%2]: %3: %4: %5, %6",diag_tickTime,"chapter1.sqf","XfMissionChapterExecute","Civilian dead",[_civ,typeof _civ], Time];
			};
		} foreach (units _civ_grp);
		
		sleep 10;
		_initial_civ_count = count (units _civ_grp);
		// 1) Create using direct group func
		// _pos_attackers = [_random_town_pos, DM_Reinforcement_Men_Range] call XfGetRanPointCircleOuter;
		// for [{_i = 0}, {_i < _enemy_troops}, { _i = _i + 1 }] do {
			// _grpSoldiers = [d_enemy_side,[_pos_attackers,100],["chapter1_random_town_zone","noveh","aware","buildings"],floor(random(5))] call XfMissionCreateFootmenGroup;
			// _attacking_groups set [ count _attacking_groups, _grpSoldiers];
			// (leader _grpSoldiers) doMove _random_town_pos;
		// };
		// 2) Create using reinforcement function and return value
		_attacking_groups = [d_enemy_side,_random_town_pos,_random_town_pos_size,_enemy_troops,0,[]] call XfMissionReinforcementMen;
		// _attacking_groups = d_c_attacking_grps;
		{ [_enemies, units _x] call XfArrayPushStack;
		} foreach _attacking_groups;
		_pos = [0,0,0];
		_i = 0;
		while { ((_pos distance [0,0,0]) <= 0) && _i < count _attacking_groups  AND DM_Mission_Mission_CanRun} do {
			_pos = getPos (leader (_attacking_groups select _i));
			_i = _i + 1;
		};
		if ((_pos distance [0,0,0]) > 0) then {
			_dir = [_pos, _random_town_pos] call XfDirTo;
			_dir_str = [_dir, [], true] call XfCompassDir;
			if (_dir_str == "") then { _dir_str = [_dir] call XfCompassDir; };
			["STR_MF_M_POGROM_SIGHTED",_dir_str] call XfMissionMessageToAll;
		};
	};
	diag_log Format["(%1)[%2]: %3: %4: %5, %6",diag_tickTime,"chapter1.sqf","XfMissionChapterExecute","Entering the loop",[_players,_enemy_troops,_initial_civ_count, (count (waypoints _civ_grp)),DM_Mission_RandomReinforcement, _reinforcement,(count _attacking_groups),(count _enemies),_dir,_attacking_groups], Time];
	while {DM_Mission_Chapter_CanRun AND DM_Mission_Mission_CanRun} do {
		sleep 10;
		_enemy_counts = ([_random_town_pos,_random_town_pos_size,d_enemy_side] call XfMissionGetZoneSideCount) select 0;
		
		// We check if there are alive players left in the base
		_players_found = true;
		if (X_MP) then {
			_players_found = false;
			{
				if (([(getPos _x), _random_town_pos, _random_town_pos_size * 3] call XfPointInCircle) && isplayer _x && alive _x) exitWith { _players_found = true; };
			}foreach playableUnits;
		} else {
			if (alive player) then { _players_found = ([(getPos player), _random_town_pos, _random_town_pos_size * 3] call XfPointInCircle); };
		};
		_civ_count = {alive _x} count _civilians;
		
		if (!_players_found || _civ_count <= 0) then {
			["DefendTheTown","", "","",[],"Failed"] call XfMissionTask;
			DM_Mission_Chapter_CanRun = false;
			_chapter_succeeded = false;
		} else {
			_active_enemies = 0;
			{
				if (!isnull _x) then {
					if (alive _x) then {
						_active_enemies = _active_enemies + 1;
					};
				};
			} foreach _enemies;
			if (_active_enemies <= 4) then {
				_units = [];
				{ 
					if (_x != grpNull) then {
						_grp = _x;
						{
							_units set [ count _units, [_x, alive _x]];
						} foreach units _grp
					};
				} foreach _attacking_groups;
				diag_log Format["(%1)[%2]: %3: %4: %5, %6",diag_tickTime,"chapter1.sqf","XfMissionChapterExecute","Enemies Dead",[_attacking_groups,_active_enemies,_units], Time];
				DM_Mission_Chapter_CanRun = false;
				_chapter_succeeded = true;
				["DefendTheTown","", "","",[],"Succeeded"] call XfMissionTask;
				sleep 30;
			} else {
				for [{_i = 0},{_i < (count _attacking_groups)},{_i = _i + 1}] do {
					_grp = _attacking_groups select _i;
					if (alive (leader _grp)) then {
						if (((leader _grp) distance _random_town_pos) > _random_town_pos_size) then {
							(leader _grp) doMove _random_town_pos;
						} else {
							_grp setBehaviour "COMBAT";
							_grp setSpeedMode "FULL";
						};
						_grp setCombatMode "RED";
						_grp setSpeedMode "FULL";
					} else {
						diag_log Format["(%1)[%2]: %3: %4: %5, %6",diag_tickTime,"chapter1.sqf","XfMissionChapterExecute","RemoveGroup",[_attacking_groups,_i,(leader _grp)], Time];
						_remove_group = true;
						if (count (units _grp) > 0) then {
							{ if (alive _x) then { _remove_group = false; };
							} foreach units _grp;
						};
						if (_remove_group) then { _attacking_groups set [_i, "XXDELXX"]; };
					};
				};
				_attacking_groups = _attacking_groups - ["XXDELXX"];
				if ((count _attacking_groups) <= ceil(_enemy_troops / 2) && DM_Mission_RandomReinforcement > 0 && _reinforcement > 0 && time > _reinf_next) then {
					diag_log Format["(%1)[%2]: %3: %4: %5, %6",diag_tickTime,"chapter1.sqf","XfMissionChapterExecute","Reinforcement",[(count _attacking_groups),ceil(_enemy_troops / 2),DM_Mission_RandomReinforcement, _reinforcement, _reinf_next, _reinf_timer], Time];
					_reinf_count = _enemy_troops - (count _attacking_groups);
					if (_reinf_count > _reinforcement) then { _reinf_count = _reinforcement; };
					[d_enemy_side,_random_town_pos,_random_town_pos_size,_reinf_count,0,[]] call XfMissionReinforcementMen;
					_attacking_groups = d_c_attacking_grps;
					_reinforcement = _reinforcement - _reinf_count;
					_reinf_next = time + (_reinf_timer / DM_Mission_RandomReinforcement);
				};
			};
		};
	};
	sleep 15;
	if (DM_Mission_Mission_CanRun) then {
		if (_chapter_succeeded) then {
			call XfMissionChapterSuccess;
		} else {
			call XfMissionChapterFailure;
		};
	} else {
		diag_log Format["(%1)[%2]: %3; %4",diag_tickTime,"chapter1.sqf","XfMissionChapterExecute","Mission canceled!"];
	};
	sleep 30;
	_players_found = true;
	_enemy_count = 100;
	While {DM_Mission_Mission_CanRun && _enemy_count > 1 && _players_found} do {
		sleep 5;
		if (X_MP) then {
			_players_found = false;
			{
				if (([(getPos _x), _random_town_pos, _random_town_pos_size * 3] call XfPointInCircle) && isplayer _x) exitWith { _players_found = true; };
			} foreach playableUnits;
		} else {
			_players_found = ([(getPos player), _random_town_pos, _random_town_pos_size * 3] call XfPointInCircle);
		};
		_enemy_count = (([_random_town_pos,(_random_town_pos_size * 3),d_enemy_side] call XfMissionGetZoneSideCount) select 0);
		if (d_mission_debug_messages) then { diag_log Format["(%1)[%2]: %3: %4: player:%5  enemies:%6",diag_tickTime,"chapter1.sqf","XfMissionChapterExecute","Chapter End Check",_players_found,_enemy_count]; };
	};
	// Just in case a reinforcement is already on the way.
	call XfMissionCancelReinforcement;
	call XfMissionChapterCleanUp;
	DM_Mission_Chapter_Runs = False;
};

XfMissionChapterSetup={
	private ["_random_town","_random_town_pos","_random_town_pos_size","_troops_power","_troops_coeff","_grpSpecOps","_i"];
	diag_log Format["(%1)[%2]: %3; %4 %5",diag_tickTime,"chapter1.sqf","XfMissionChapterSetup","Starting Initialization:",DM_Mission_Name];
	
	_random_town = [];
	_random_town_pos = [];
	_random_town_pos_size = 150;
	_i_tries = 20;
	while { ((count _random_town) <= 0) && (_i_tries > 0) && DM_Mission_Mission_CanRun && DM_Mission_Chapter_CanRun } do {
		_random_town = [[XF_MAP_LOCATION_TYPE_VILLAGE]] call XfMissionGetRandomSpot;
		// diag_log Format["(%1)[%2]: %3: %4: %5",diag_tickTime,"chapter1.sqf","XfMissionChapterSetup","Picked up", _random_town];
		if ( count _random_town > 0 ) then {
			_random_town_pos = _random_town select XF_MAP_LOCATION_CENTER;
			_random_town_pos_size = _random_town select XF_MAP_LOCATION_SIZE;
		};
	};
	if ((count _random_town) <= 0) exitWith {"STR_MF_RANDOMSITEFAILED" call XfMissionMessageToAll; DM_Mission_Mission_CanRun = false; DM_Mission_Chapter_CanRun = false;};
	_random_town_pos_name = _random_town select XF_MAP_LOCATION_DISPLAYNAME;
	
	DM_Chapter_Location = _random_town;
	DM_Chapter_Position = _random_town_pos;
	
	// This indicates where the mission takes place
	[_random_town_pos,_random_town_pos_size,_random_town_pos_name] call XfMissionCurrentPosition;
	
	_teleporter = [_random_town_pos] call XfMissionRandomStartTeleporter;
	// If no spot found, we get back an empty position.
	if (count (_teleporter select 0) > 0) then {
		[false,["chapter1_start_position",(_teleporter select 0), "ICON", "ColorBlue", [1,1],"",(_teleporter select 1),"hd_start","",1]] call XfMissionMarker;
	};
	
	DM_Mission_Civilians = 1;
	_players = call XPlayersNumber;
	_amount = 15 + _players;
	_kamikaze = DM_Mission_KamikazeUnit;
	DM_Mission_KamikazeUnit = false;
	DM_VIP = [[_random_town_pos,_random_town_pos_size * 0.8],"CIV",_amount] call XfMissionCivilianSpawn;
	DM_Mission_KamikazeUnit = _kamikaze;

	[false,["chapter1_random_town_zone", _random_town_pos, "ELLIPSE", "ColorRed", [_random_town_pos_size,_random_town_pos_size],"",0,"","BDiagonal",0.5]] call XfMissionMarker;
	
	["DefendTheTown","STR_MF_M_POGROM_TASK_DEFEND", ["STR_MF_M_POGROM_TASK_DEFEND_DESC",_random_town_pos_name],"",[],"Created"] call XfMissionTask;
};

XfMissionChapterSuccess={
	diag_log Format["(%1)[%2]: %3; %4",diag_tickTime,"chapter1.sqf","XfMissionChapterSuccess","Starting"];
	"STR_MF_M_POGROM_SUCCESS" call XfMissionMessageToAll;
	DM_Mission_Chapter_Success = 1;
};

XfMissionChapterFailure={
	diag_log Format["(%1)[%2]: %3; %4",diag_tickTime,"chapter1.sqf","XfMissionChapterFailure","Starting"];
	"STR_MF_M_POGROM_FAILURE" call XfMissionMessageToAll;
	DM_Mission_Chapter_Success = -1;
};

// Self-explanatory
XfMissionChapterCleanUp={
	diag_log Format["(%1)[%2]: %3; %4",diag_tickTime,"chapter1.sqf","XfMissionChapterCleanUp","Starting"];
	// Giving an empty position places the teleporter back to the hangar, closing the hangar.
	[[],0] call XfMissionPlaceStartTeleporter;
	[] call XfMissionCleanMarkers;
	[] call XfMissionCleanTriggers;
	[] call XfMissionCleanTasks;
};

DM_Mission_Chapter_Compiled = true;